﻿using Vowei.Core.Models;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using System.Collections.Generic;
using Vowei.Data;
using System.Diagnostics;
using Vowei.Data.Models;
using Vowei.Data.Helpers;

namespace vowei.test
{   
    /// <summary>
    /// 测试Milestone与其外键之间的联系
    ///</summary>
    [TestClass()]
    public class MilestoneTest : TestBase
    {       
        /// <summary>
        ///Tasks 的测试
        ///</summary>
        [TestMethod()]
        public void TasksTest()
        {
            using (var impl = new VoweiContextImpl())
            {
                var context = new VoweiContext(impl);
                var project = new Project()
                {
                    Title = "TasksTest_Project",
                    Owner = Setting.DefaultUserName,
                    StartDate = DateTime.Now,
                    DueDate = null
                };
                impl.Projects.Add(project);

                var milestone = new Milestone()
                {
                    Title = "TasksTest_Milestone1",
                    StartDate = DateTime.Now,
                    DueDate = DateTime.Now + TimeSpan.FromDays(30)
                };
                impl.Milestones.Add(milestone);
                project.Children.Add(milestone);

                milestone = new Milestone()
                {
                    Title = "TasksTest_Milestone2",
                    StartDate = DateTime.Now + TimeSpan.FromDays(31),
                    DueDate = DateTime.Now + TimeSpan.FromDays(60)
                };
                impl.Milestones.Add(milestone);
                project.Children.Add(milestone);

                var requirement = new Requirement()
                {
                    Title = "TasksTest_Requirement1",
                    AssignedTo = Setting.DefaultUserName,
                    BusinessValue = 12345,
                    BelongsToMilestone = project.Children.First()
                };
                requirement.Children.Add(new Task()
                {
                    Title = "TasksTest_Task1",
                    AssignedTo = Setting.DefaultUserName,
                    StartDate = DateTime.Now,
                    DueDate = DateTime.Now + TimeSpan.FromHours(4)
                });
                requirement.Children.Add(new Task()
                {
                    Title = "TasksTest_Task2",
                    AssignedTo = Setting.DefaultUserName,
                    StartDate = DateTime.Now + TimeSpan.FromHours(4),
                    DueDate = DateTime.Now + TimeSpan.FromHours(8)
                });
                impl.Requirements.Add(requirement);
                impl.Requirements.Add(new Requirement()
                {
                    Title = "TasksTest_Requirement2",
                    AssignedTo = Setting.DefaultUserName,
                    BusinessValue = 12345,
                    BelongsToMilestone = milestone
                });
                impl.SaveChanges();

                var tasks = project.AllTasks(context);
                Assert.IsNotNull(tasks);
                Assert.AreNotEqual(0, tasks.Count());

#if TRACE
                foreach (var task in tasks)
                    Trace.WriteLine(string.Format("[TasksTest]-[{0}]: {1}", task.ID, task.Title));
#endif
            }
        }

        [TestMethod]
        public void UnAssignedMilestonesTest()
        {
            Guid id = Guid.Empty;
            using (var impl = new VoweiContextImpl())
            {
                var milestone = impl.Create<Milestone>("UnAssignedMilestonesTest_Milestone");
                var context = new VoweiContext(impl);
                id = milestone.ID;
                impl.Milestones.Add(milestone);
                impl.SaveChanges();

                var actual = context.UnAssignedMilestone();
                // 这个测试用例，还没有想明白，针对用户创建的，没有关联
                // 项目的里程碑，应该如何处理，因此暂时先让它执行不通过
                Assert.AreNotEqual(0, actual.Count());
                Assert.IsTrue(actual.Any(m => m.ID == id));
            }

            using (var impl = new VoweiContextImpl())
            {
                var context = new VoweiContext(impl);
                var actual = context.UnAssignedMilestone();
                Assert.AreNotEqual(0, actual.Count());
                Assert.IsTrue(actual.Any(m => m.ID == id));
            }
        }

        [TestMethod]
        public void RequirementImportDataBasicTest()
        {
            var project = CreateProjectHelper("RequirementImportDataBasicTest");
            var requirement = CreateRequirementHelper("RequirementImportDataBasicTest", project);
            var tickets = new List<Ticket>(new Ticket[] {
                CreateTaskHelper("Task 1", project),
                CreateTaskHelper("Task 2", project),
                CreateTaskHelper("Task 3", project),
                CreateRequirementHelper("Requirement 1", project)
            });

            using (var impl = new VoweiContextImpl())
            {
                foreach (var ticket in tickets)
                    requirement.Children.Add(ticket);

                impl.Requirements.Add(requirement);
                impl.SaveChanges();
            }

            var title = "Task 2 updated title";
            tickets[1].Title = title;
            tickets.Add(CreateTaskHelper("Task 4", project));

            foreach (var ticket in tickets)
            {
                var milestone = ticket.BelongsToMilestone;
                ticket.BelongsToMilestone = null;
                ticket.BelongsToMilestoneId = milestone.ID;
            }

            using (var impl = new VoweiContextImpl())
            {
                var context = new VoweiContext(impl);
                requirement = (Requirement)context.Requirements.Find(requirement.ID);
                ImportHelper.ImportDataTo(requirement, context, tickets, Setting.DefaultFormUser);

                var actual = context.Requirements.Include("Children").Query.First(r => r.ID == requirement.ID);
                Assert.AreEqual(5, actual.Children.Count());

                Assert.IsTrue(actual.Children.Any(t => t.Title == title));
                title = tickets[4].Title;
                Assert.IsTrue(actual.Children.Any(t => t.Title == title));
            }

            // 导入的时候，缺少的ticket不会被删除！
            title = tickets[0].Title;
            tickets.RemoveAt(0);
            tickets.Add(CreateTaskHelper("Task 5", project));
            tickets[tickets.Count - 1].BelongsToMilestone = null;
            tickets[tickets.Count - 1].BelongsToMilestoneId = project.ID;

            using (var impl = new VoweiContextImpl())
            {
                var context = new VoweiContext(impl);
                requirement = (Requirement)context.Requirements.Find(requirement.ID);
                ImportHelper.ImportDataTo(requirement, context, tickets, Setting.DefaultFormUser);

                var actual = context.Requirements.Include("Children").Query.First(r => r.ID == requirement.ID);
                Assert.AreEqual(6, actual.Children.Count());

                Assert.IsTrue(actual.Children.Any(t => t.Title == title));
                title = tickets[tickets.Count - 1].Title;
                Assert.IsTrue(actual.Children.Any(t => t.Title == title));
            }
        }
    }
}
